#ifndef BARCODE_DETAIL_EAN13_MASK_HPP_INLCUDED
#define BARCODE_DETAIL_EAN13_MASK_HPP_INLCUDED

#include "../ean13_types.hpp"

#include <boost/cstdint.hpp>

#include <utility>

namespace barcode { namespace detail {

static boost::uint8_t l_[] = { 13, 25, 19, 61, 35, 49, 47, 59, 55, 11 };
static boost::uint8_t r_[] = { 114, 102, 108, 66, 92, 78, 80, 68, 72, 116 };
static boost::uint8_t g_[] = { 39, 51, 27, 33, 29, 57, 5, 17, 9, 23 };

template < class Type, int N >
boost::int8_t lrg_digit( Type (&lrg_)[ N ] , boost::uint8_t binary_ )
{
	for ( boost::int8_t i_ = 0; i_ < N; ++i_ )
	{
		if ( lrg_[ i_ ] == binary_ )
			return i_;
	}

	return -1;
}

static const std::size_t ean13_mask_length_ = _ean13_left_length + _ean13_right_length;

static boost::uint8_t* ean13_mask_[][ ean13_mask_length_ ] =
{
	{ l_, l_, l_, l_, l_, l_, r_, r_, r_, r_, r_, r_ }//LLLLLL RRRRRR
	, { l_, l_, g_, l_, g_, g_, r_, r_, r_, r_, r_, r_ }//LLGLGG RRRRRR
	, { l_, l_, g_, g_, l_, g_, r_, r_, r_, r_, r_, r_ }//LLGGLG RRRRRR
	, { l_, l_, g_, g_, g_, l_, r_, r_, r_, r_, r_, r_ }//LLGGGL RRRRRR
	, { l_, g_, l_, l_, g_, g_, r_, r_, r_, r_, r_, r_ }//LGLLGG RRRRRR
	, { l_, g_, g_, l_, l_, g_, r_, r_, r_, r_, r_, r_ }//LGGLLG RRRRRR
	, { l_, g_, g_, g_, l_, l_, r_, r_, r_, r_, r_, r_ }//LGGGLL RRRRRR
	, { l_, g_, l_, g_, l_, g_, r_, r_, r_, r_, r_, r_ }//LGLGLG RRRRRR
	, { l_, g_, l_, g_, g_, l_, r_, r_, r_, r_, r_, r_ }//LGLGGL RRRRRR
	, { l_, g_, g_, l_, g_, l_, r_, r_, r_, r_, r_, r_ }//LGGLGL RRRRRR
};

typedef std::pair< boost::uint8_t*, boost::int8_t > code_digit_type;

inline code_digit_type ean13_digit( boost::uint8_t binary_ )
{
	boost::int8_t digit_ = lrg_digit( l_, binary_ );
	if ( digit_ != -1 )
		return code_digit_type( l_, digit_ );

	digit_ = lrg_digit( g_, binary_ );
	if ( digit_ != -1 )
		return code_digit_type( g_, digit_ );

	digit_= lrg_digit( r_, binary_ );
	if ( digit_ != -1 )
		return code_digit_type( r_, digit_ );

	return code_digit_type( 0, -1 );
}

}}

#endif //BARCODE_DETAIL_EAN13_MASK_HPP_INLCUDED

